#pragma once

using std::cout;
using std::endl;
using std::string;

typedef struct _PLAYER_STATUS
{
    string Name;
    unsigned int HP;
    unsigned int MP;
}PLAYER_STATUS, * PPLAYER_STATUS;

class CMemTo    //  Memento
{
    PLAYER_STATUS m_PlayerStatus;

public:
    CMemTo(PPLAYER_STATUS status)
    {
        m_PlayerStatus.Name = status->Name;
        m_PlayerStatus.HP = status->HP;
        m_PlayerStatus.MP = status->MP;
    }
    virtual ~CMemTo() { }

public:
    PLAYER_STATUS& GetPlayerStatus() { return m_PlayerStatus; }
};

class CPlayer   //  Originator
{
    PLAYER_STATUS m_PlayerStatus;

public:
    CPlayer()
    {
        m_PlayerStatus.Name = "Player";
        m_PlayerStatus.HP = 100;
        m_PlayerStatus.MP = 100;
    }
    CPlayer(string strName)
    {
        m_PlayerStatus.Name = strName;
        m_PlayerStatus.HP = 100;
        m_PlayerStatus.MP = 100;
    }
    virtual ~CPlayer() { }

public:
    void ShowPlayerStatus()
    {
        cout << "Name: " << m_PlayerStatus.Name << ", HP: " << m_PlayerStatus.HP 
            << ", MP: " << m_PlayerStatus.MP << endl;
    }

    void SetPlayerStatus(unsigned int HP, unsigned int MP)
    {
        m_PlayerStatus.HP = HP;
        m_PlayerStatus.MP = MP;
    }

public:
    CMemTo* Save()
    {
        return new CMemTo(&m_PlayerStatus);
    }

    void Load(CMemTo* lpMemTo)
    {
        PLAYER_STATUS& status = lpMemTo->GetPlayerStatus();
        m_PlayerStatus.Name = status.Name;
        m_PlayerStatus.HP = status.HP;
        m_PlayerStatus.MP = status.MP;
    }
};

class CSnapshot //  CareTaker
{
    CMemTo* m_lpMemTo;

public:
    CSnapshot() { }
    virtual ~CSnapshot() { }

public:
    void SetMemTo(CMemTo* lpMemTo) { m_lpMemTo = lpMemTo; }
    CMemTo* GetMemTo() const { return m_lpMemTo; }
};
